package tcpserver;

import frame.util.FlowUtil;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import tcpserver.handler.RFIDChannelInitializer;

public class RFIDServer {

    private final int port;

    private ServerBootstrap bootstrap;

    private ChannelFuture channelFuture;

    private EventLoopGroup bossGroup = new NioEventLoopGroup(), workerGroup = new NioEventLoopGroup();

    public RFIDServer(int port) {

        this.port = port;

        this.bootstrap = new ServerBootstrap();

        bootstrap.group(bossGroup, workerGroup)
                 .channel(NioServerSocketChannel.class)
                 .childHandler(new RFIDChannelInitializer())

                 // BossConnection Options

                 .option(ChannelOption.SO_BACKLOG, 128)

                 // WorkerConnection Options

                 .childOption(ChannelOption.SO_KEEPALIVE, true)
                 .childOption(ChannelOption.TCP_NODELAY, true);
    }

    public synchronized void startAtBackground() {

        if(channelFuture != null) return;

        channelFuture = FlowUtil.silent(() -> bootstrap.bind(port).sync(), ChannelFuture.class.cast(null));

        new Thread(() -> {

            try {

                channelFuture.channel().closeFuture().sync();

            } catch(Exception e) {

                e.printStackTrace();

            } finally {

                bossGroup.shutdownGracefully();

                workerGroup.shutdownGracefully();
            }

        }).start();
    }

    public synchronized void shutdownGracefully() {

        bossGroup.shutdownGracefully();

        workerGroup.shutdownGracefully();
    }
}
